#ifndef _SLIDER_CLASS_HPP_
#define _SLIDER_CLASS_HPP_

#include "include.hpp"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>


class xlider_class {
friend class presentation;
friend class xlider_generator;
public:

 	//--- all numbers are relative to the width or height
	double slide_width;
	double slide_height;
	double margin_top;
	double margin_left;
	double margin_right;

	double background_scale;
	string background_color;
	string background_image;

	string home_path;
	vector<string> garbage;
	
	void clean_garbage(){
		for(int i=0;i<garbage.size();i++)remove(garbage[i].c_str());
	}

	void trim(string& txt){
		string stmp("");
		int a=0,s=txt.length()-1;
		while((txt[a]=='\r')||
			  (txt[a]=='\t')||
			  (txt[a]=='\n')|| 
			  (txt[a]==' '))a++;
		
		while((txt[s]=='\r')||
			  (txt[s]=='\t')||
			  (txt[s]=='\n')|| 
			  (txt[s]==' '))s--;
		
		// \n is accepted
		for(;a<=s;a++) {
			if((txt[a]=='\r')||(txt[a]=='\t')) continue;
			if(txt[a]==' ') if(txt[a-1]==' ') continue;
			stmp+=txt[a];
		}
		txt.assign(stmp);
	}


	void convert_color(string clr, int &r, int &g, int &b, int& a){
		if(clr==""){r=g=b=0; return;}

		if(clr=="red"){r=255;g=b=0;return;}
		if(clr=="green"){g=255;r=b=0;return;}
		if(clr=="blue"){b=255;r=g=0;return;}
		if(clr=="white"){r=255;g=255;b=255;return;}
		if(clr=="black"){r=0;g=0;b=0;return;}
		if(clr=="yellow"){r=255;g=255;b=0;return;}
		if(clr=="cyan"){r=0;g=255;b=255;return;}
		if(clr=="magenta"){r=255;g=0;b=255;return;}

		if(clr[0]!='#'){r=g=b=0;return;}
		if(clr.size()<7){r=g=b=0;return;}
		char hex[5]="0x??", *ep;					
		hex[2]=clr[1];hex[3]=clr[2];r=strtol(hex,&ep,16);
		hex[2]=clr[3];hex[3]=clr[4];g=strtol(hex,&ep,16);
		hex[2]=clr[5];hex[3]=clr[6];b=strtol(hex,&ep,16);
		if(clr.size()>=9){
			hex[2]=clr[7];hex[3]=clr[8];a=strtol(hex,&ep,16);
		} else a=255;
	}

	void convert_color(string clr, int &r, int &g, int &b){
		int a;
		convert_color(clr,r,g,b,a);
	}
	
	void convert_color(string clr, double &r, double &g, double &b, double &a) {
		int ir,ig,ib,ia;
		convert_color(clr,ir,ig,ib,ia);
		r=(double)ir/255.0;
		g=(double)ig/255.0;
		b=(double)ib/255.0;
		a=(double)ia/255.0;
	}

	void convert_color(string clr, double &r, double &g, double &b) {
		double a;
		convert_color(clr,r,g,b,a);
	}

	bool file_exist(string fname){
		struct stat filestat;
		if(stat(fname.c_str(), &filestat)) return false;
		return true;
	}
	
	void assert(bool cond, string message) {
		if(!cond) THROW(message.c_str());
	}

	void assert(bool cond, string message, string val){
		if(!cond){
			char st[512];
			sprintf(st, "%s: %s", message.c_str(), val.c_str());
			THROW(st);
		}
	}
	void assert(bool cond, string message, int val){
		if(!cond){
			char st[512];
			sprintf(st, "%s: %d", message.c_str(), val);
			THROW(st);
		}
	}
	void assert(bool cond, string message, double val){
		if(!cond){
			char st[512];
			sprintf(st, "%s: %f", message.c_str(), val);
			THROW(st);
		}
	}
	
	// gives xml declaration file
	string get_font_xml(string fontname) {
		string fullpath=fontname+".xml";
		// check font declaration file
		if(!file_exist(fullpath))fullpath=(home_path+"/fonts/"+fontname+".xml");
		assert(file_exist(fullpath),"can not find font file", fullpath);
		return fullpath;
	}

	// if files exist in the current directory--> take it
	string get_fontpath(string fontname){		
		xml_config_reader xfont(get_font_xml(fontname).c_str());
		string font_filename=xfont.PeekString("font.path.directory");
		font_filename.append(xfont.GetString("font.path.file"));
		
		if(!file_exist(font_filename))font_filename=(home_path+"/fonts/"+font_filename);
		assert(file_exist(font_filename),"can not find font file", font_filename);
		
		return font_filename;
	}	
	
	string get_themepath(string themename){
		string fullpath=themename+".xml";
		if(!file_exist(fullpath))fullpath=(home_path+"/themes/"+themename+".xml");
		assert(file_exist(fullpath),"can not find theme file", fullpath);
		return fullpath;
	}
	
	string get_scriptpath(string scriptname){
		string fullpath=scriptname+".script";
		if(!file_exist(fullpath))fullpath=(home_path+"/script/"+scriptname+".script");
		assert(file_exist(fullpath),"can not find script file", fullpath);
		return fullpath;
	}
	
	void call_script(string script, string options){
		string cmd("sh ");
		cmd.append(get_scriptpath(script)+" "+options);
		system(cmd.c_str());
	}

	string get_imagepath(string imagename){
		string fullpath=imagename;
		if(!file_exist(fullpath))fullpath=(home_path+"/images/"+imagename);
		assert(file_exist(fullpath),"can not find file", fullpath);
		return fullpath;
	}

	bool file_type(string fn, string ext){
		string sear(".");sear.append(ext);
		if(fn.find(sear,fn.length()-sear.length())==string::npos)
			return false;
		return true;
	}
	
	string cat(string filename){
		ifstream fl(filename.c_str());
		assert(!fl.fail(), "can not open file", filename);
		string s,rets;
		while(getline(fl,s))rets.append(s+"\n");
		return rets;
	}
	
	string basename(string name){
		int slash=name.find_last_of("/");
		if(slash==string::npos)slash=0;else slash++;
		return name.substr(slash);
	}
	
	string basename(string name, string ext){
		string bname=basename(name);
		int idx=bname.length()-ext.length();
		string dotext(".");dotext.append(ext);
		if(bname.substr(idx-1)==dotext) return bname.substr(0,idx-1);
		else return bname;
	}
	
	string basename(string name, bool noext){
		string bname(basename(name));
		if(noext){
			int dot=name.find_last_of(".");
			if(dot==string::npos)return bname;
			else return bname.substr(0,dot);
		} else return bname;
	}
	
	string as_string(int val){
		char st[64];
		sprintf(st,"%d",val);
		return st;
	}

	string as_string(size_t val){return as_string((int)val);}

	string as_string(double val, const char* format=NULL){
		char st[64];
		if(format)sprintf(st,format,val);
		else sprintf(st,"%0.2f",val);
		return st;
	}

};

#endif
